package com.example.sxt_practise.reflection;


import com.example.sxt_practise.annotation.MyAnnotation;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

/**
 * 泛型:java采用了泛型擦除的机制引入泛型,java的泛型仅仅是给编译器(javac)使用的,确保数据的安全性和免去强制类型转换的麻烦.但是,一旦编译完成,所有和泛型有关的类型全部擦除
 * @author gaofeng
 * @date 2022年06月05日 17:07
 */
public class GenericTest {
    public static void main(String[] args) {
        // 获取指定方法参数泛型信息
        try {
            Method method = GenericTest.class.getMethod("test1", Map.class, List.class);
            // 获取带泛型参数类型
            Type[] parameterTypes = method.getGenericParameterTypes();
            for (Type parameterType : parameterTypes) {
                System.out.println(parameterType);
                if (parameterType instanceof ParameterizedType) {
                    System.out.println("*" + parameterType);
                    Type[] genericTypes = ((ParameterizedType) parameterType).getActualTypeArguments();
                    for (Type genericType : genericTypes) {
                        System.out.println("泛型类型" + genericType);
                    }
                }
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }

        // 获取指定方法返回值泛型信息
        try {
            Method test2 = GenericTest.class.getMethod("test2", null);
            Type returnType = test2.getGenericReturnType();
            if (returnType instanceof ParameterizedType) {
                System.out.println("*" + returnType);
                Type[] types = ((ParameterizedType) returnType).getActualTypeArguments();
                for (Type type : types) {
                    System.out.println("返回值,泛型类型: " + type);
                }
            }
            Annotation[] annotations = test2.getAnnotations();
            for (Annotation annotation : annotations) {
                System.out.println("注解" + annotation);
            }

//            SuppressWarnings annotation = test2.getAnnotation(SuppressWarnings.class);
            MyAnnotation annotation = test2.getAnnotation(MyAnnotation.class);
            System.out.println("注解" + annotation);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }

    @SuppressWarnings("all")
    public void test1(Map<String, Student> map, List<Student> list) {
        System.out.println("GenericTest test1");
    }

    @SuppressWarnings("all")
    @MyAnnotation
    public Map<Integer, Student> test2() {
        System.out.println("GenericTest test2");
        return null ;
    }
}
